home *** CD-ROM | disk | FTP | other *** search
- """A module that reads JPEG files using the SGI Compression Library.
-
- This module should only be used in a python-interpreter with the cl
- module configured, otherwise the builtin imgjpeg module is better."""
-
- import cl
- from imgformat import rgb, rgb_b2t, xrgb8, xrgb8_b2t, xgrey, xgrey_b2t, \
- rgb8, rgb8_b2t, grey, grey_b2t, error
- import sys
-
- class reader:
- def __init__(self, file):
- if type(file) == type(''):
- self._filename = file
- self._file = f = open(file, 'rb')
- else:
- self._filename = '<open file>'
- self._file = f = file
- header = f.read(16)
- scheme = cl.QueryScheme(header)
- self._decompressor = decomp = cl.OpenDecompressor(scheme)
- size = cl.QueryMaxHeaderSize(scheme)
- if size > len(header):
- header = header + f.read(size - len(header))
- headersize = decomp.ReadHeader(header)
- self.width = decomp.GetParam(cl.IMAGE_WIDTH)
- self.height = decomp.GetParam(cl.IMAGE_HEIGHT)
- self.format_choices = rgb, rgb_b2t, xrgb8, xrgb8_b2t, xgrey, xgrey_b2t
- self.format = rgb # default format
-
- def args(self):
- return self.__dict__
-
- def read(self):
- if self.format in (rgb, rgb_b2t):
- original_format = cl.RGBX
- elif self.format in (xrgb8, xrgb8_b2t, rgb8, rgb8_b2t):
- original_format = cl.RGB332
- elif self.format in (xgrey, xgrey_b2t, grey, grey_b2t):
- original_format = cl.GRAYSCALE
- else:
- raise error, 'Unknown format'
- if self.format in (rgb_b2t, xrgb8_b2t, xgrey_b2t, rgb8_b2t, grey_b2t):
- orientation = cl.BOTTOM_UP
- else:
- orientation = cl.TOP_DOWN
- width = self.width
- if original_format == cl.RGB332 and sys.platform == 'irix5':
- # Irix 5.3 uses more buffer than it should, so allocate some extra
- width = (width + 3) & ~3
- bbp = cl.BytesPerPixel(original_format)
- params = [cl.ORIGINAL_FORMAT, original_format,
- cl.ORIENTATION, orientation,
- cl.FRAME_BUFFER_SIZE, width * self.height * bbp]
- decomp = self._decompressor
- decomp.SetParams(params)
- self._file.seek(0)
- data = decomp.Decompress(1, self._file.read())
- if self.width & 1 and \
- decomp.GetParam(cl.INTERNAL_FORMAT) == cl.FORMAT_YCbCr422DC:
- # IRIX has difficulty with odd-width images. It rounds
- # the width down to an even number, so we double the
- # right-most pixel so that the image gets the original
- # width again.
- import string
- rv = []
- w = (self.width - 1) * bbp
- for i in range(0, self.height * w, w):
- rv.append(data[i:i+w] + data[i+w-bbp:i+w])
- return string.join(rv, '')
- # only return the image, not the extra space
- return data[:self.width*self.height*bbp]
-
- def write(self, data):
- raise error, 'Cannot write() to reader'
-
- class writer:
- def __init__(self, file):
- if type(file) == type(''):
- self._filename = file
- self._fp = None
- else:
- self._filename = "<open file>"
- self._fp = file
- self.format_choices = rgb, rgb_b2t, xrgb8, xrgb8_b2t, xgrey, xgrey_b2t
- self.format = rgb
-
- def args(self):
- return self.__dict__
-
- def _get(self, attr):
- try:
- return getattr(self, attr)
- except AttributeError:
- raise error, "Required attribute '%s' missing"%attr
-
- def read(self):
- raise error, 'Cannot read() from writer'
-
-
- def write(self, data):
- width = self._get('width')
- height = self._get('height')
- format = self._get('format')
- if format in (rgb, rgb_b2t):
- original_format = cl.RGBX
- elif format in (xrgb8, xrgb8_b2t):
- original_format = cl.RGB332
- elif format in (xgrey, xgrey_b2t):
- original_format = cl.GRAYSCALE
- else:
- raise error, 'Unknown format'
- if format in (rgb_b2t, xrgb8_b2t, xgrey_b2t):
- orientation = cl.BOTTOM_UP
- else:
- orientation = cl.TOP_DOWN
- if width * height * cl.BytesPerPixel(original_format) != len(data):
- raise error, 'Incorrect datasize'
- params = [cl.ORIGINAL_FORMAT, original_format,
- cl.ORIENTATION, orientation,
- cl.IMAGE_WIDTH, width,
- cl.IMAGE_HEIGHT, height]
- try:
- quality = self.quality
- except AttributeError:
- pass
- else:
- params.append(cl.QUALITY_FACTOR)
- params.append(quality)
- compressor = cl.OpenCompressor(cl.JPEG)
- compressor.SetParams(params)
- data = compressor.Compress(1, data)
- if self._fp:
- file = self._fp
- else:
- file = open(self._filename, 'wb')
- file.write(data)
-